package com.xxx.yuedong.community.service.impl;

import com.xxx.yuedong.common.exception.YuedongException;
import com.xxx.yuedong.community.controller.form.FollowForm;

import com.xxx.yuedong.community.db.cache.RedisCache;
import com.xxx.yuedong.community.db.dao.FollowDao;
import com.xxx.yuedong.community.pojo.Follow;
import com.xxx.yuedong.community.service.FollowService;
import com.xxx.yuedong.mine.db.dao.UserDao;
import com.xxx.yuedong.mine.pojo.vo.BeFollowVO;
import com.xxx.yuedong.mine.pojo.vo.FollowVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 关注表的业务类
 *
 * @Author YinXi
 * @Versin 1.0.0
 * @Date 2023/8/3
 */
@Slf4j
@Service
public class FollowServiceImpl implements FollowService {
    @Autowired
    private FollowDao followDao;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private UserDao userDao;

    /**
     * 实现点击关注业务
     * - 关注者的id和被关注者的id是同一个检测
     * - 被关注者id是否存在检测
     * - 重复关注检测
     * - 调用DAO层写入tb_follow
     * - 判断被关注的id是否关注了关注者的id（双向关注）
     */
    @Override
    public String getFollow(FollowForm followForm) {
//        关注者的id和被关注者的id是同一个（防止自己关注自己）
        if (followForm.getToId().equals(followForm.getFromId())) {
            log.warn("异常消息用户id{}：【自己关注了自己】",followForm.getFromId());
            throw new YuedongException(HttpStatus.SC_INTERNAL_SERVER_ERROR,"账号异常，已封号,请联系管理员");
        }
//        被关注者id是否存在
        if (userDao.searchUserInfo(followForm.getToId()) == null) {
            log.warn("异常消息用户id{}：【被关注者的id{}不存在】",followForm.getFromId(),followForm.getToId());
            throw new YuedongException(HttpStatus.SC_LOCKED,"对方账号状态异常无法关注");
        }
//        重复关注检测（逻辑严谨性）
        List<FollowForm> followForms = redisCache.list(RedisCache.KEY_FOLLOW);
        if(!followDao.isToId(followForm).isEmpty() || followForms.contains(followForm)){
            log.warn("异常消息用户id{}：【用户重复关注】",followForm.getFromId());
            throw  new YuedongException(HttpStatus.SC_NO_CONTENT,"已经关注过该账号");
        }

//        Redis缓存到其中
        Long get =  redisCache.insert(followForm,RedisCache.KEY_FOLLOW);
        if (get <= 0) {
            log.error("异常消息用户id{}：【Redis数据库异常无法新增数据】",followForm.getFromId());
            throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
        }
        FollowForm form = new FollowForm();
        form.setToId(followForm.getFromId());
        form.setFromId(followForm.getToId());
//        判断被关注的id是否关注了关注者的id
        if(!followDao.getFroms(followForm).isEmpty()||followForms.contains(form)){
            return "相互关注";
        }
        return "已关注";
    }
    /**
     * 实现点击取消关注业务
     * - 判断是否关注了被关注的账号
     */
    @Override
    public void outFollow(FollowForm followForm) {
//        判断是否关注了被关注的账号
        List<FollowForm> followForms = redisCache.list(RedisCache.KEY_FOLLOW);
        if(followDao.isToId(followForm).isEmpty() || !followForms.contains(followForm)){
            log.warn("异常消息用户id{}：【未关注过被关注账号用户id{}】",followForm.getFromId(),followForm.getToId());
            throw new YuedongException(HttpStatus.SC_NO_CONTENT,"未关注");
        }
//        int out = followDao.deleteFollower(followForm);
        Long out = redisCache.insert(followForm,RedisCache.KEY_OUTFOLLOW);
        if (out <= 0) {
            log.warn("异常消息用户id{}：【Redis数据库异常无法新增数据】",followForm.getFromId());
            throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
        }
    }

    /**
     * 获取当前关注者id的被关注者的数量
     * -获取为null时使用0作为代替
     */
    @Override
    public int countFollow(Long formId) {
       if(followDao.countByToId(formId) == null){
           return 0;
       }
       return followDao.countByToId(formId);
    }

    /**
     *获取当前关注者id的粉丝数量
     * -获取为null时使用0进行代替
     */
    @Override
    public int countToFollow(Long formId) {
       if(followDao.countByFormId(formId)==null){
           return 0;
       }
       return followDao.countByFormId(formId);
    }

    @Override
    public List<BeFollowVO> queryBeFollowList(Long userId) {
        List<BeFollowVO> followVOS = followDao.queryBeFollowList(userId);
        return followVOS;
    }

    /**
     * 判断关注者是否关注过被关注者
     */
    @Override
    public List<FollowForm> isFollower(FollowForm form) {
        return followDao.isToId(form);
    }

    /**
     * 重构Redis缓存
     */
    @Override
    public void rebulidFollowList() {
        List<FollowForm> followForms = redisCache.list(RedisCache.KEY_FOLLOW);
        List<FollowForm> outFollowForms = redisCache.list(RedisCache.KEY_OUTFOLLOW);
        if(!followForms.isEmpty()){
            int num = followDao.insertFollower(followForms);
            if (num<=0){
                log.error("【MySQL数据库异常无法新增数据】");
                throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
            }
        }
        if(!outFollowForms.isEmpty()){
            int num = followDao.deleteFollower(outFollowForms);
            if (num<=0){
                log.error("【MySQL数据库异常无法新增数据】");
                throw new YuedongException(HttpStatus.SC_BAD_REQUEST,"系统繁忙请稍好尝试……");
            }
        }
        redisCache.deleteList(RedisCache.KEY_FOLLOW);
        redisCache.deleteList(RedisCache.KEY_OUTFOLLOW);
    }

}
